﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace DotNetCommon;
/// <summary>
/// 字符串实现的36进制，使用0-9A-Z表示。它和8进制、10进制、16进制本质上一样(不同于Base64)
/// </summary>
public static class Base36
{
    private const string Base36Characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    /// <summary>
    /// 将给定的数字编码为<see cref="Base36"/>字符串。
    /// </summary>
    /// <param name="input">要编码的数字。</param>
    /// <returns>编码 <paramref name="input"/> 为字符串。</returns>
    public static string Encode(long input)
    {
        AssertUtil.BeTrue<ArgumentException>(input >= 0, "输入不能是负的。");

        var arr = Base36Characters.ToCharArray();
        var result = new Stack<char>();
        while (input != 0)
        {
            result.Push(arr[input % 36]);
            input /= 36;
        }
        return new string([.. result]);
    }

    /// <summary>
    /// 将<see cref="Base36"/>编码的字符串解码为长整数。
    /// </summary>
    /// <param name="input">要解码的数字。</param>
    /// <returns>解码 <paramref name="input"/> 为长整数。</returns> 
    public static long Decode(string input)
    {
        AssertUtil.NotNull(input);

        var reversed = input.ToUpper().Reverse();
        long result = 0;
        var pos = 0;
        foreach (var c in reversed)
        {
            result += Base36Characters.IndexOf(c) * (long)Math.Pow(36, pos);
            pos++;
        }
        return result;
    }
}
